package com.wxg.example.rest;

import com.wxg.example.dao.mysql.model.User;
import com.wxg.example.dao.mysql.model.UserBak;
import com.wxg.example.service.UserBakService;
import com.wxg.example.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

/**
 * @author void
 * @date 2021/8/12 11:56
 * @desc
 */
@Slf4j
@RestController
public class UserController {
    
    @Autowired
    private UserService userService;
    @Autowired
    private UserBakService userBakService;
    
    @GetMapping("/batchInsert")
    public void batchInsert(){
        List<User> userList = new ArrayList<>();
        Random random = new Random();
        for(int i=0;i<10000;i++){
            User user = new User();
            user.setName("wxg"+i);
            user.setAge(random.nextInt(80));
            user.setAddress("深圳市南山区");
            userList.add(user);
        }
        userService.batchInsert(userList);
    }

    /**
     * 单线程转移
     */
    @GetMapping("/transfer1")
    public void transfer1(){
        long d = System.currentTimeMillis();
        List<User> list = userService.listUser(1, 10000);
        for (User user : list) {
            this.handlerUser(user);
        }
        System.out.println("整体耗时:"+(System.currentTimeMillis()-d));
    }
    
    @GetMapping("/transfer2")
    public Long transfer2(){
        long d = System.currentTimeMillis();
        List<User> list = userService.listUser(1, 10000);
        
        ExecutorService es = Executors.newFixedThreadPool(100);
        List<FutureTask> taskList = new ArrayList<>();
        for (User user : list) {
            FutureTask<Integer> futureTask = new FutureTask<>(new MysqlFutureTask(userBakService, user));
            es.submit(futureTask);
            taskList.add(futureTask);
        }
        es.shutdown();
        
        try {
            while(!es.isTerminated()){
                if(es.awaitTermination(5, TimeUnit.SECONDS)){
                    log.info("线程全部执行完成");
                }else{
                    log.info("线程还未全部执行完成");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            es.shutdownNow();
            Thread.currentThread().interrupt();
        }catch (Exception e){
            es.shutdownNow();
        }
        long r = System.currentTimeMillis()-d;
        log.info("整体耗时:"+(r));
        return r;
    }
    
    private void handlerUser(User user){
        UserBak userBak = new UserBak();
        BeanUtils.copyProperties(user, userBak);
        if(userBak.getAge()>40){
            userBak.setAgeDesc("中老年人");
        }else{
            userBak.setAgeDesc("青壮年人");
        }
        userBakService.insert(userBak);
    }
    
    private class MysqlFutureTask implements Callable<Integer> {
        
        private UserBakService userBakService;
        private User user;

        public MysqlFutureTask(UserBakService userBakService, User user) {
            this.userBakService = userBakService;
            this.user = user;
        }

        @Override
        public Integer call() throws Exception {
            System.out.println("线程名:"+Thread.currentThread().getName()+" 执行插入");
            UserBak userBak = new UserBak();
            BeanUtils.copyProperties(user, userBak);
            if(userBak.getAge()>40){
                userBak.setAgeDesc("中老年人");
            }else{
                userBak.setAgeDesc("青壮年人");
            }
            userBakService.insert(userBak);
            return 1;
        }
    }
}
